package org.ricks.game.action;

import org.ricks.game.common.ActionErrorEnum;
import org.ricks.game.common.MsgException;
import org.ricks.game.entity.ItemEntity;
import org.ricks.game.proto.common.Common;
import org.ricks.game.proto.login.Login;
import org.ricks.game.proto.player.Player;
import org.ricks.game.rpc.RpcContext;
import org.ricks.game.service.UserService;
import org.ricks.ioc.anno.Action;
import org.ricks.ioc.anno.Autowired;
import org.ricks.ioc.event.anno.EventReceiver;
import org.ricks.ioc.utils.Logger;
import org.ricks.net.action.ActionExceptionEvent;
import org.ricks.net.action.anno.ActionMethod;
import org.ricks.net.action.context.FlowContext;
import org.ricks.net.action.context.head.DefHeadMeta;
import org.ricks.net.action.context.head.HeadMeta;
import org.ricks.net.action.context.head.RpcHeadMeta;
import org.ricks.net.action.parser.TypeReference;
import org.ricks.net.action.rpc.RpcClient;
import org.ricks.net.action.rpc.RpcSessionManager;
import org.ricks.orm.OrmContext;

import java.util.Objects;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

@Action
public class UserAction {

    public static void main(String[] args) {
        String name = "Alice";
        int age = 30;
        String info = "姓名：${name}，年龄：${age + 5}"; // 直接支持表达式计算
        System.err.println(info);

        // 编译错误：布尔值无法直接插入字符串
        String error = "状态：${true}";
        System.err.println(error);

    }

    @Autowired
    private UserService userService;


    @EventReceiver
    public void actionExceptionEvent(ActionExceptionEvent<? extends HeadMeta> actionExceptionEvent) {
        Throwable throwable = actionExceptionEvent.getThrowable();
        FlowContext<? extends HeadMeta> flowContext = actionExceptionEvent.getContext();
        HeadMeta headMeta = flowContext.headMeta;

        if (throwable instanceof MsgException msgException) {
            System.err.println("业务异常 -- " + msgException);
            if (headMeta.isRpc()) {
                // RPC请求：使用rpcError响应
                flowContext.rpcError(msgException.getMsgCode(), msgException.getMessage());
            } else {
                // 普通请求：使用错误cmd=10000响应，并在消息体中包含原始cmd
                Common.RickErrorPush errorPush = Common.RickErrorPush.newBuilder()
                        .setCode(msgException.getMsgCode())
                        .setMsg(msgException.getMessage())
                        .build();

                // 创建错误HeadMeta，cmd固定为10000
                HeadMeta errorHeadMeta = new DefHeadMeta((short) 10000);
                // 发送消息
                flowContext.writeBytes(errorHeadMeta, errorPush.toByteArray());
            }
            return;
        }

        Logger.error("内部异常", throwable);
    }
    private Common.ErrorPush buildError (int error) {
        return Common.ErrorPush.newBuilder().setError(error).build();
    }

    @ActionMethod(command = 1)
    public void test(FlowContext<DefHeadMeta> context) throws ExecutionException, InterruptedException, TimeoutException {

//        Logger.warn(addMethod("我开始调用新增方法-----------------------"));
        var item = OrmContext.getOrmManager().getEntityCaches(ItemEntity.class);
        var entity = item.loadOrCreate(1L);
        ActionErrorEnum.itemNumErr.assertTrue(Objects.nonNull(entity));
        entity.getBaseItems().put(1000, 1L);
        item.update(entity);
//        throw new MsgException((short) 99,"测试断言机制");
//        Login.LoginRequest data = context.deserialize(new TypeReference<Login.LoginRequest>(){});
        Login.LoginRequest data = context.deserialize(Login.LoginRequest.class);
        String s = userService.test();

        Logger.info("收到客户端请求 msgId :{}",data.getRpcId());
        RpcClient rpcClient = RpcContext.get(1);
        CompletableFuture<String> future =  rpcClient.invoke((short) 10, "smart- rpc - ricks is god", String.class);

        String aa = future.get(1000L, TimeUnit.MILLISECONDS);
        Logger.info(" 收到Rpc 调用  -- " + aa);
        // 优化后：直接通过 TypeReference 传递泛型类型
        Logger.info(System.currentTimeMillis() + " -- websocket协议 - 进入测试代码！@  ---- " + data.getUsername() + " " +
                "-----  " + s  + "  ------- " + data.getDid() );
        Login.LoginResponse.Builder builder = Login.LoginResponse.newBuilder();
        builder.setPlayerInfo(buildPlayerInfo(aa));
        builder.setRpcId(data.getRpcId());
        context.writeBytes(builder.build().toByteArray());
    }


//    public String addMethod (String a) {
//
//        return a + "addMethod 正在被调用 ！";
//    }

    private Player.PlayerInfo buildPlayerInfo ( String a) {
        Player.PlayerInfo.Builder builder = Player.PlayerInfo.newBuilder();
        builder.setAccount("i am demo . upi are god ?");
        builder.setLv(999);
        builder.setName("fuck you  王老师！");
        builder.setExp(1);
        builder.setRoleId(a);
        return builder.build();
    }



    @ActionMethod(isRpc = true, command = 10)
    public void rpcTest (FlowContext<RpcHeadMeta> flowContext) {
//        Logger.info("data字节流：{}", Arrays.toString(flowContext.getData()));
//        Logger.info("rpc..................." + new String(flowContext.getData()));
        int msgId = flowContext.headMeta.rpcRequestId();
        Logger.info("GameA服务器收到客户端消息 msgid:{}", msgId);

        if(msgId == 100000) {
            Logger.info("服务器收到最后一条客户端消息 msgid:{}", msgId);

        }
        if(msgId % 10000== 0) {
            Logger.info("收到消息 msgId:{}", msgId);
        }
//        Logger.info("收到消息 msgId:{}", msgId);

        flowContext.rpcResponse("我市GameB - rpc，玛德");
    }

}
